package com.example.login.service;

import com.example.login.controller.SendMessageController;
import com.example.login.mapper.OrderMapper;
import com.example.login.entity.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.example.login.util.JwtUtil.verifyToken;

/**
 * @Description: 手动注入RestTemplate
 *
 * <p>启动报错：找不到RestTemplate
 *
 * @auther: zpq
 * @date: 2020/11/5 4:13 下午
 */


@Service
public class OrderServiceImp implements OrderService {

    @Autowired
    private OrderMapper orderDao;

    //用来发送http请求的
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方法

    public  String sendDirectMessage(Map<String, Object> map) {
        String messageId = String.valueOf(UUID.randomUUID());

        map.put("messageId",messageId);

        //将消息携带绑定键值：TestDirectRouting 发送到交换机TestDirectExchange
        rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
        return "ok";
    }

    //验证jwt
//    public Boolean verifyToken(Map<String, Object> queryInfo){
//        HttpHeaders headers = new HttpHeaders();
//        Map<String,String> body = new HashMap<>();
//        body.put("token", queryInfo.get("token").toString());
//        return restTemplate.postForObject("http://localhost:8092/jwt/testToken",new HttpEntity<>(body, headers), Boolean.class);
//    }

    public List<String> getBuildings(){
        List<String> buildings = getAllBuildingName();
        return buildings;
    }

    public Result grabDorm(HttpServletRequest request, HttpServletResponse response, Map<String, Object> queryInfo){
        Result result = new Result();
//        //验证token是否正确
//        if(!verifyToken(queryInfo)){
//            result.setStatus(500);
//            result.setMsg("用户未登录，请重新登录");
//            return result;
//        }
//        System.out.println("token验证成功");

        if(!verifyToken((String) queryInfo.get("token"))){
            result.setStatus(500);
            result.setMsg("用户未登录，请重新登录");
            return result;
        }
        //得到认证码
        try{
            //todo: 需要判断用户是否已经被分配宿舍
            String myAuthCode = queryInfo.get("myAuthCode").toString();
            UserAuthCode authCodeTemp = findIsExistAuthCode(myAuthCode);
            System.out.println(authCodeTemp);
            if(null == authCodeTemp){//不存在该认证码
                result.setStatus(500);
                result.setMsg("提交了不存在的认证码");
                System.out.println(myAuthCode + "不存在");
                return result;
            }
            int uid = authCodeTemp.getUid();
            List<Map<String,String>> allInfo = new ArrayList<>();
            List<Integer> userUids = new ArrayList<>();
            Map<String,String> myInfo =  findUserInfoByUid(uid); //根据uid查询用户信息
            System.out.println("myInfo:"+myInfo.toString());
            allInfo.add(myInfo);
            userUids.add(uid);
            String gender = myInfo.get("gender");

            //判断同住人的性别和认证码是否存在
            //将数组转为List<String>类型
            System.out.println("还没有添加同住人");
            String[] otherCodes = request.getParameterValues("codes");

            //List<String> otherCodes = convertToList(queryInfo.get("codes"), String.class);
            System.out.println(queryInfo);
            //System.out.println(queryInfo.get("codes"));
            //System.out.println(otherCodes.toString());
            int num ;
            if(otherCodes!=null){
                num =otherCodes.length+1;
                System.out.println("进入了同住人判断");
                for (String otherCode : otherCodes) {
                    UserAuthCode temp = findIsExistAuthCode(otherCode);
                    if(null == temp){
                        result.setStatus(500);
                        result.setMsg("提交了不存在的认证码");
                        System.out.println(otherCode+"不存在");
                        return result;
                    }
                    int uidTemp = temp.getUid();
                    Map<String,String> infoTemp =  findUserInfoByUid(uidTemp); //查询信息
                    if(!infoTemp.get("gender").equals(gender)){
                        //同住人性别不符合
                        result.setStatus(500);
                        result.setMsg("同住人性别不一致");
                        return result;
                    }
                    allInfo.add(infoTemp); //存储信息
                    userUids.add(uidTemp);
                }
            }
            else {
                num =1;
                System.out.println("同住人为空");
            }


            //获取到了所有人的信息，便于选宿舍成功后展示出来

            String buildingName = queryInfo.get("choiceBuilding").toString();  //这行没有choiceBuilding参数，返回空指针
            //String buildingName = "Building One";

            //根据buidingName gender 人数 去寻找是否存在空床位

            System.out.println("开始查询空床位");

                //int num =1;
                //查询空床位

                List<Map<String, Object>> roomResults = orderDao.getDormByOrder(buildingName, gender, num);
                System.out.println(roomResults);

                if(roomResults.size() == 0){
                    result.setStatus(400);
                    result.setMsg("很遗憾，你没有抢到目标宿舍");
                    System.out.println("没有抢成功");
                    return result;
                }
                //Random rand = new Random();
                //int index = rand.nextInt(num/2);
                //Map<String, Object> room = roomResults.get(index);
                Map<String, Object> room = roomResults.get(0);
                int roomId = (int) room.get("roomId");
                String roomName = (String) room.get("roomName");


                updateGrabedRoom(roomId, num);
            System.out.println("完成宿舍更新");
                //完成更新宿舍

            System.out.println("开始向消息队列发送数据");
                //生成要插入的订单信息
                Map<String,Object> body = new HashMap<>();
                //2. Order表中的信息
                body.put("roomId",roomId);
                body.put("gender", gender);
                body.put("num", num);
                body.put("uid", uid);
                body.put("submitTime",getCurrentTime());
                body.put("buildingName",buildingName);
                body.put("isSuccess","1");
                body.put("userUids",uid);
                sendDirectMessage(body);

            System.out.println("已经成功向消息队列发送了信息");

            //restTemplate.postForObject("http://39.105.35.184:15672/TestDirectQueue",new HttpEntity<>(body, headers), Boolean.class);
                /*
                //更新数据库，需要传递过去的信息有，roomId,num,order
                // 1. 更新DormRoom房间信息
                updateGrabedRoom(roomId, num);
                // 2. 写入Order表
                Order order = new Order();
                int buildingId = findBuildingIdByBuildingName(buildingName); //这一行在消息队列中处理
                order.setGender(gender);
                order.setDormBuildingId(buildingId);//这一行在消息队列中处理
                order.setIsSuccess("1");
                order.setStuNum(num);
                order.setUid(uid); //提交人的uid
                order.setSubmitTime(getCurrentTime());
                insertOrder(order);   //这一行在消息队列中处理
                // 3. 写入OrderInfo表
                insertAllOrderInfo(order.getId(), userUids); //这一行在消息队列中处理
                // 4. 写入用户宿舍关联表
                insertUserDormCorrinfo(roomId, userUids); //这一行在消息队列中处理


 */
                result.setStatus(1);
                result.setMsg("选宿舍成功");
                Map<String,Object> data = new HashMap<>();
                data.put("buildingName", buildingName);
                data.put("gender", gender);
                data.put("roomID", roomId);
                data.put("roomName", roomName);
                data.put("studentInfo", allInfo);
                result.setData(data);
            result.setStatus(1);
            result.setMsg("选宿舍成功");

        }catch (Exception e){
            System.out.println(e);
            result.setStatus(500);
            result.setMsg("数据 库操作失败");
        }
        return result;
    }

    public static <T> List<T> convertToList(Object object, Class<T> tClass){
        List<T> result = new ArrayList<>();
        if(object instanceof List<?>){
            for(Object o : (List<?>) object){
                result.add(tClass.cast(o));
            }
            return result;
        }
        return null;
    }

    public String getCurrentTime(){
        Date date=new Date();
        SimpleDateFormat temp=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String dateStr=temp.format(date);
        return dateStr;
    }


    @Override
    public List<Map<String, String>> countFreeRooms() {
        return orderDao.countFreeRooms();
    }

    @Override
    public List<String> getAllBuildingName() {
        return orderDao.getAllBuildingName();
    }

    @Override
    public Map<String, String> findUserInfoByUid(int uid) {
        return orderDao.findUserInfoByUid(uid);
    }

    @Override
    public UserAuthCode findIsExistAuthCode(String authCode) {
        return orderDao.findIsExistAuthCode(authCode);
    }

    @Override
    public List<Map<String, Object>> getDormByOrder(String buildingName, String gender, int num) {
        return orderDao.getDormByOrder(buildingName, gender, num);
    }

    @Override
    public int updateGrabedRoom(int roomId, int num) {
        return orderDao.updateGrabedRoom(roomId, num);
    }

    @Override
    public Boolean insertAllOrderInfo(int orderId, List<Integer> uid) {
        for(int i=0; i<uid.size(); i++){
            try{
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setOrderId(orderId);
                orderInfo.setUid(uid.get(i));
                int isSuccess = orderDao.insertOrderInfo(orderInfo);
                if(isSuccess == 1){
                    //成功
                    System.out.println("插入uid "+ uid + " 成功");
                }else{
                    return false;
                }
            }catch (Exception e){
                System.out.println(e);
            }
        }
        return true;
    }

    @Override
    public int findBuildingIdByBuildingName(String buildingName) {
        return orderDao.findBuildingIdByBuildingName(buildingName);
    }

    @Override
    public int insertOrder(Order order) {
        return orderDao.insertOrder(order);
    }

    @Override
    public Boolean insertUserDormCorrinfo(int roomID, List<Integer> uid) {
        for(int i=0; i<uid.size(); i++){
            try{
                UserDormCorrinfo userDormCorrinfo = new UserDormCorrinfo();
                userDormCorrinfo.setDormRoomId(roomID);
                userDormCorrinfo.setCreateTime( getCurrentTime() );
                userDormCorrinfo.setUid(uid.get(i));
                int isSuccess = orderDao.insertUserDormCorrinfo(userDormCorrinfo);
                if(isSuccess == 1){
                    //成功
                    System.out.println("插入uid "+ uid + " 成功");
                }else{
                    return false;
                }
            }catch (Exception e){
                System.out.println(e);
            }
        }
        return true;
    }
}
